<template>
    <div>
        <!-- 导入 -->
		<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" :before-close="handleDialogClose"
			@open="resetFormOnOpen">
			<el-progress v-if="isUploading" :percentage="uploadProgress" :stroke-width="10" status="success" striped
				striped-flow style="margin-bottom: 15px;" />
			<el-upload ref="uploadRef" class="file-uploader" action="#" :http-request="customHttpRequest"
				:before-upload="beforeFileUpload" :on-success="handleUploadSuccess" :on-error="handleUploadError"
				:show-file-list="false" :accept="acceptedFileTypesString" :on-exceed="handleUploadExceed">
				<el-button type="success" :loading="isUploading">
					<el-icon>
						<UploadFilled />
					</el-icon> {{ isUploading ? '上传中...' : '选择文件' }}
				</el-button>
				<template #tip>
					<div class="el-upload__tip">
						支持上传文档 (excel)。大小不超过 {{ MAX_FILE_SIZE_MB }}MB。
					</div>
				</template>
			</el-upload>
		</el-dialog>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps } from 'vue';
import { tokenManager } from '@/utils/token'
import {config} from '@/config/index'
import {useUserStore} from '@/stores/user'
const userStore = useUserStore()
// import { defineProps, defineEmits, computed } from 'vue';
const emit = defineEmits(['uploadSuccessFun'])
const props = defineProps({
    action: {
        type: String,
        default: ''
    }
})

// const emit = defineEmits(['change', 'delete']);
// ====================================================================
import { ElMessage, ElMessageBox } from 'element-plus';
import type { UploadInstance, UploadProps, UploadRawFile, UploadRequestOptions, UploadFile } from 'element-plus';
import { UploadFilled, View, Download } from '@element-plus/icons-vue'; // 假设已在 main.ts 全局注册
import feedback from '@/utils/feedback';

// --- 配置常量 ---
// const action = ref(`${config.baseUrl}${config.urlPrefix}/upload/file`)
const action = ref(`${import.meta.env.VITE_API_BASE_URL}/article/${props.action}`)
const headersRequest = computed(() => ({
	// token: tokenManager.getToken(),
}))
const YOUR_UPLOAD_API_ENDPOINT = '/api/your-actual-upload-endpoint'; // <--- [需要你填写] 你的实际文件上传接口地址
const MAX_FILE_SIZE_MB = 3; // <--- [可修改] 最大文件大小限制 (MB)

// 定义可预览和可下载的文件类型
const PREVIEWABLE_EXTENSIONS = ['excel','xlsx','xlsm','xls']; // PDF 通常也可以用类似 gview 的方式预览
const ALL_ACCEPTED_EXTENSIONS = [...PREVIEWABLE_EXTENSIONS];

const acceptedFileTypesString = computed(() => {
	return ALL_ACCEPTED_EXTENSIONS.map(ext => `.${ext}`).join(',');
	// 或者更精确的 MIME 类型，例如：
	// 'application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf,application/zip,application/x-rar-compressed'
});


interface UploadedFileInfo {
	name: string;
	url: string;
	uri: string;
	type: string; // MIME type or extension
	canPreview: boolean;
	canDownload: boolean;
}

const dialogVisible = ref(false);
const uploadRef = ref<UploadInstance>();
const isUploading = ref(false);
const uploadProgress = ref(0);
const uploadedFile = ref<UploadedFileInfo | null>(null);

const dialogTitle = computed(() => uploadedFile.value ? `文件信息：${uploadedFile.value.name}` : '上传文件');
const fileUrlForInputDisplay = computed(() => uploadedFile.value?.uri || '');

const fileSelectId = ref<number>();


const handleDialogClose = (done: () => void) => {
	if (isUploading.value) {
		ElMessage.warning('文件正在上传中，请稍候...');
		return;
	}
	if (uploadedFile.value) {
		ElMessageBox.confirm('已上传的文件信息将会丢失，确定关闭吗？')
			.then(() => {
				done();
			})
			.catch(() => { });
	} else {
		done();
	}
};

const resetFormOnOpen = () => {
	uploadedFile.value = null;
	isUploading.value = false;
	uploadProgress.value = 0;
	if (uploadRef.value) {
		uploadRef.value.clearFiles();
	}
};

// --- 上传逻辑 ---
const customHttpRequest = async (options: UploadRequestOptions) => {
    console.log(options)
	const file = options.file;
	const formData = new FormData();
	formData.append('file', file); // 'file' 通常是后端期望的字段名，请根据你的后端调整
	// --- [可添加] 如果你的接口需要其他参数，在这里添加 ---
	// formData.append('userId', 'currentUser123');
	// formData.append('uploadType', 'document');
	// ----------------------------------------------------

	isUploading.value = true;
	uploadProgress.value = 0;

	const xhr = new XMLHttpRequest();

	return new Promise((resolve, reject) => {
		xhr.upload.onprogress = (event) => {
			if (event.lengthComputable) {
				const percentComplete = Math.round((event.loaded / event.total) * 100);
				uploadProgress.value = percentComplete;
				if (options.onProgress) {
					options.onProgress({ percent: percentComplete } as any);
				}
			}
		};

		xhr.onload = () => {
			isUploading.value = false;
			if (xhr.status >= 200 && xhr.status < 300) {
				try {
					const responseData = JSON.parse(xhr.responseText);
					console.log('responseData==========================', responseData, file);
					// --- [需要你调整] 根据你的后端响应结构来判断成功和获取数据 ---
					// 假设你的后端成功时返回类似:
					// { success: true, data: { url: '...', originalName: '...', fileType: 'docx' } }
					// 或者 { code: 200, data: { file_url: '...', file_name: '...' } }
					if (responseData.code == 0) { //示例判断条件
						// console.log('Calling options.onSuccess from customHttpRequest for file:', file.name); // <-- 添加日志
						// const serverUrl = responseData.data.url;
						// const serverFileName = responseData.data.originalName || file.name;
						// const serverFileType = responseData.data.fileType || getFileExtension(serverFileName); // 你可能需要从后端获取准确类型
						// options.onSuccess({ url: serverUrl, originalName: serverFileName, uri: responseData.data.uri }); // 将关键信息传递给onSuccess
						// resolve(responseData);
						feedback.msgSuccess('上传成功')
                        emit('uploadSuccessFun')
                        dialogVisible.value = false
					} else {
						const errorMsg = responseData.msg || '服务器返回了错误或数据格式不正确。';
						feedback.notifyError_vice(errorMsg, {duration: 0})
						// ElMessage.error(errorMsg);
						options.onError(new Error(errorMsg) as any);
						reject(new Error(errorMsg));
					}
					// -----------------------------------------------------------
				} catch (e) {
					console.log(e)
					// feedback.alertError(e)
					feedback.notifyError_vice('解析服务器响应失败。', {duration: 0});
					options.onError(e as Error as any);
					reject(e);
				}
			} else {
				let errorMsg = `上传失败，状态码: ${xhr.status}`;
				try {
					const errorResponse = JSON.parse(xhr.responseText);
					errorMsg = errorResponse.message || errorMsg; // 尝试从响应体获取更详细错误
				} catch (e) { /* 忽略解析错误 */ }
				feedback.notifyError_vice(errorMsg, {duration: 0});
				options.onError(new Error(errorMsg) as any);
				reject(new Error(errorMsg));
			}
		};

		xhr.onerror = () => {
			isUploading.value = false;
			uploadProgress.value = 0;
			feedback.notifyError_vice('上传过程中发生网络错误。', {duration: 0});
			options.onError(new Error('网络错误') as any);
			reject(new Error('网络错误'));
		};

		xhr.onabort = () => {
			isUploading.value = false;
			uploadProgress.value = 0;
			// ElMessage.info('上传已取消。'); // onError中统一处理消息或options.onError本身就处理
			options.onError(new Error('上传取消') as any);
			reject(new Error('上传取消'));
		};

		xhr.open('POST', action.value, true);
		// --- 在这里添加请求头 ---
		// 检查 headersRequest 是否有值并且是一个对象
		if (headersRequest.value && typeof headersRequest.value === 'object') {
			// 遍历 headersRequest 对象中的所有键值对
			for (const headerName in headersRequest.value) {
				// 确保只遍历对象自身的属性，而不是原型链上的属性
				if (Object.prototype.hasOwnProperty.call(headersRequest.value, headerName)) {
					const headerValue = headersRequest.value[headerName];
					// 确保 headerValue 是字符串类型，因为 setRequestHeader 的值需要是字符串
					if (headerValue !== null && headerValue !== undefined) {
						xhr.setRequestHeader(headerName, String(headerValue));
					}
				}
			}
		}
		// --- [可添加] 如果你的接口需要认证头部 (例如 JWT Token) ---
		const token = tokenManager.getToken()
		if (token) {
		  xhr.setRequestHeader('Token', `${token}`);
		}
		// xhr.setRequestHeader('X-Custom-Header', 'YourValue');
		// --------------------------------------------------------

		xhr.send(formData);
	});
};

const getFileExtension = (filename: string): string => {
	return filename.slice(((filename.lastIndexOf(".") - 1) >>> 0) + 2).toLowerCase();
};
// 上传前
const beforeFileUpload: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {
	if (isUploading.value) {
		ElMessage.warning('已有文件正在上传，请稍候。');
		return false;
	}

	const extension = getFileExtension(rawFile.name);
	const isValidType = ALL_ACCEPTED_EXTENSIONS.includes(extension);

	if (!isValidType) {
		ElMessage.error(`不支持的文件类型: .${extension}。请上传 ${ALL_ACCEPTED_EXTENSIONS.join(', ')} 类型的文件。`);
		return false;
	}

	if (rawFile.size / 1024 / 1024 > MAX_FILE_SIZE_MB) {
		ElMessage.error(`文件大小不能超过 ${MAX_FILE_SIZE_MB}MB！`);
		return false;
	}
	uploadedFile.value = null; // 清除旧文件信息
	return true;
};
// 上传成功
const handleUploadSuccess: UploadProps['onSuccess'] = (
	response: any, // 这是 customHttpRequest 中 options.onSuccess 传递过来的对象 { url: '...', originalName: '...' }
	uploadFileRef: UploadFile
) => {
	console.log('handleUploadSuccess CALLED. Response:', response, 'File name:', uploadFileRef.name); // <-- 添加日志
	const extension = getFileExtension(response.originalName || uploadFileRef.name);
	uploadedFile.value = {
		name: response.originalName || uploadFileRef.name!,
		url: response.url, // <--- 确保这是后端返回的、可用于预览或下载的公开URL
		uri: response.uri,
		type: extension, // 或者使用 uploadFileRef.raw?.type (MIME) 如果更准确
		canPreview: PREVIEWABLE_EXTENSIONS.includes(extension),
		canDownload: true, // 所有成功上传的文件都可下载
	};
	ElMessage.success(`文件handleUploadSuccess "${uploadedFile.value.name}" 上传成功！`);
	isUploading.value = false;
	uploadProgress.value = 100;
};
// 上传失败
const handleUploadError: UploadProps['onError'] = (
	// error: Error, uploadFile: UploadFile, uploadFiles: UploadFiles
) => {
	// 具体的错误消息应该在 customHttpRequest 中通过 ElMessage.error() 显示了
	uploadedFile.value = null;
	isUploading.value = false;
	uploadProgress.value = 0;
};

const handleUploadExceed: UploadProps['onExceed'] = (files) => {
	console.log('handleUploadExceed CALLED.上传中');
	if (isUploading.value) {
		ElMessage.warning('已有文件正在上传，请稍候。');
		return;
	}
	uploadRef.value!.clearFiles();
	const file = files[0] as UploadRawFile;
	uploadRef.value!.handleStart(file);
};


const open = () => {
    dialogVisible.value = true;
}

defineExpose({
    open
})
</script>

<style scoped></style>